package kz.alamty.dev.service;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Transaction;

import kz.alamty.dev.dao.AnswerDAO;
import kz.alamty.dev.dao.QuestionDAO;
import kz.alamty.dev.dao.UserDAO;
import kz.alamty.dev.exception.NonAllowedVoteException;
import kz.alamty.dev.exception.NonAuthorizingException;
import kz.alamty.dev.obj.Answer;
import kz.alamty.dev.obj.Question;
import kz.alamty.dev.obj.StatisticObj;
import kz.alamty.dev.obj.User;
import kz.alamty.dev.util.TheConstant;

public class TheService {
	private AnswerDAO aDao = new AnswerDAO();
	private QuestionDAO qDao = new QuestionDAO();
	private UserDAO uDao = new UserDAO();
	
	/**
	 * add user account
	 * @return
	 */  
	public void addUser(User user)
	{
		try {
			Transaction trans= uDao.getSession().beginTransaction();
			trans.begin();
			uDao.save(user);
			trans.commit();
		} catch (RuntimeException e) {
			throw e;
		}
	}
	
	/*
	 * delete user account
	 * @return
	 */
	public void deleteAccount(User user)
	{
		Transaction trans= uDao.getSession().beginTransaction();
		trans.begin();
		uDao.delete(user);
		trans.commit();
	}
	
	@SuppressWarnings("unchecked")
	public List<Question> allQuestion()
	{
		ArrayList<Question> list = new ArrayList<Question>();
		try {
			list = (ArrayList<Question>) qDao.findAll();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
		return list;
	}
	
	/*
	 *  simple Authorizing  
	 */
	public boolean authorizing(String login, String pw)
	{
		List users = uDao.findByUser(new User(login,pw));
		return users.size()>0;
	}
	
	/*
	 *  publish the Question by owner
	 */
	public void publishQuestion(Question question) throws NonAuthorizingException  
	{
		
	    if(questionAuthentication(question))
	    {
			Transaction trans= qDao.getSession().beginTransaction();
			trans.begin();
		    qDao.save(question);
		    trans.commit();
	    }
	    else
	    	throw new NonAuthorizingException();
	}
   
	/**
	 *  before then Authenticate ,can't do any action for question
	 * @param question
	 * @return
	 */
	private boolean questionAuthentication(Question question) {
		if (question== null 
				|| question.getOwner()==null 
				|| question.getOwner().getId()==null
				|| question.getText()== null
				)
			return false;
		else
			return true;
	}

	/**
	 * close the question by owner/Administrator
	 */
	public void closeQuestion(Question question) throws NonAuthorizingException
	{
		if(questionAuthentication(question))
		{
			Transaction trans= qDao.getSession().beginTransaction();
			trans.begin();
			qDao.delete(question);
			trans.commit();
		}
		    
		else
			throw new NonAuthorizingException();
	}
	
	/**
	 *  vote to specific question by other attender not allowed by owner
	 * @param answer
	 * @throws NonAllowedVoteException 
	 */
	public void vote4Qeustion(Answer answer) throws NonAllowedVoteException
	{
		if (answer==null 
				|| !this.questionAuthentication(answer.getQuestion())
				|| isOwener(answer.getQuestion(),answer.getUser())/*owner not allow*/ 
				|| wasVoted(answer.getQuestion(),answer.getUser()) /*if already vote not allow*/
				)
		 throw new NonAllowedVoteException();
		else
		{
			Transaction trans= aDao.getSession().beginTransaction();
			trans.begin();
			aDao.save(answer);
			trans.commit();
		}
								
	}
	
	/**
	 * identifying a current user is owner of the Question
	 * @param question
	 * @param currentUser
	 * @return
	 */
	public boolean isOwener(Question question,User currentUser)
	{
		return question.getOwner().getId().equals(currentUser.getId());
			
	}
	
	/**
	 * Case scenario: one user can't vote 2 times for a question, so if 
	 * already answered for the question will be return true
	 * @param answer
	 * @param currentUser
	 * @return
	 */
	public boolean wasVoted(Question question,User currentUser)
	{
		Answer answer = new Answer();
		answer.setQuestion(question);
		answer.setUser(currentUser);
		List<Answer> list = aDao.findByExample(answer);
		return list.size()>0;
	}
	
	/**
	 * find Question by id
	 */
	public Question getQuestionbyid(Long id)
	{
		Question qes = new Question();
		qes = qDao.findById(id);
		 return qes;
	}
	
	/**
	 *  For a Question related Answser statics
	 */
	public StatisticObj getStatistic4Answer(Question question)
	{
		StatisticObj S_obj = new StatisticObj();
		S_obj.setQuestion(question);
		int count_yes = getEachChooceByQuestion(question, ""+TheConstant.ANSWER_YES);
		int count_no = getEachChooceByQuestion(question,""+TheConstant.ANSWER_NO);
		int count_unknown = getEachChooceByQuestion(question,""+TheConstant.ANSWER_UNKNOWN);
		S_obj.setHow_much_pepole_vote_No(count_no);
		S_obj.setHow_much_pepole_vote_UnKnowun(count_unknown);
		S_obj.setHow_much_pepole_vote_Yes(count_yes);
		
		return S_obj;
	}
	/**
	 * For The Question howmany "Yes|No|Unknown" result voted 
	 */
	public int getEachChooceByQuestion(Question question,String chooce)
	{
		Answer anser = new Answer();
		anser.setQuestion(question);
		anser.setChoose(chooce);
		anser.setUser(question.getOwner());
		List list = aDao.findByExample(anser);
		int count = list.size();
		return count;
	}
}
